package com.mtw.bbs.bbsUser.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mtw.bbs.bbsUser.constant.EMenuType;
import com.mtw.bbs.bbsUser.pojo.entity.RoleMenu;
import com.mtw.bbs.bbsUser.pojo.form.MenuForm;
import com.mtw.bbs.common.core.constant.ServiceConstant;
import com.mtw.bbs.userAdmin.pojo.vo.MenuVo;
import com.mtw.bbs.bbsUser.service.RoleMenuService;
import com.mtw.bbs.bbsUser.service.UserRoleService;
import com.mtw.bbs.common.core.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mtw.bbs.bbsUser.mapper.MenuMapper;
import com.mtw.bbs.bbsUser.pojo.entity.Menu;
import com.mtw.bbs.bbsUser.service.MenuService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.*;
import static com.mtw.bbs.bbsUser.utils.TreeUtil.list2Tree;

/**
 * 菜单表逻辑层
 *
 * @author mo
 * @email mo
 * @date 2023-10-23 10:15:12
 */
@Service("menuService")
@RequiredArgsConstructor
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {


    private final UserRoleService userRoleService;
    private final RoleMenuService roleMenuService;


    /**
     *获取菜单列表
     * @param qw    查询条件
     * @return
     */
    @Override
    public List<MenuVo> getPageList(LambdaQueryWrapper<Menu> qw) {


        List<Menu> list = list(qw);
        List<MenuVo> menuVoList = list.stream().map(Menu::toVo).toList();
        return  list2Tree(menuVoList);
    }


    /**
     * 获取用户拥有的菜单列表
     */
    @Override
    public List<MenuVo> getMenu(String userId) {

        Set<String> roleIds = userRoleService.queryByUserId(userId);
        if (CollectionUtils.isEmpty(roleIds)){
            return new ArrayList<>(1);
        }

        LambdaQueryWrapper<RoleMenu> rLqw = new LambdaQueryWrapper<>();
        rLqw.in(RoleMenu::getRoleId,roleIds);
        List<RoleMenu> roleMenuList = roleMenuService.list(rLqw);
        if (CollectionUtils.isEmpty(roleMenuList)){
            return new ArrayList<>(1);
        }
        List<String> menuIds = roleMenuList.stream().map(RoleMenu::getMenuId).distinct().toList();

        LambdaQueryWrapper<Menu> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Menu::getStatus, ServiceConstant.STATUS_ENABLE);
        lqw.eq(Menu::getMenuType, EMenuType.MENU);
        lqw.in(Menu::getId,menuIds);
        lqw.orderByAsc(Menu::getSort);
        lqw.orderByDesc(Menu::getCreatedDate);
        return getPageList(lqw);
    }



    /**
     * 获取用户拥有的按钮
     */
    @Override
    public List<MenuVo> getButton(String userId) {
        Set<String> roleIds = userRoleService.queryByUserId(userId);
        if (CollectionUtils.isEmpty(roleIds)){
            return new ArrayList<>(1);
        }

        LambdaQueryWrapper<RoleMenu> rLqw = new LambdaQueryWrapper<>();
        rLqw.in(RoleMenu::getRoleId,roleIds);
        List<RoleMenu> roleMenuList = roleMenuService.list(rLqw);
        if (CollectionUtils.isEmpty(roleMenuList)){
            return new ArrayList<>(1);
        }
        List<String> menuIds = roleMenuList.stream().map(RoleMenu::getMenuId).distinct().toList();

        LambdaQueryWrapper<Menu> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Menu::getStatus, ServiceConstant.STATUS_ENABLE);
        lqw.eq(Menu::getMenuType, EMenuType.BUTTON);
        lqw.in(Menu::getId,menuIds);
        lqw.orderByAsc(Menu::getSort);
        return list(lqw).stream().map(Menu::toVo).toList();
    }


    /**
     * 获取全部菜单列表
     *
     * @param id 菜单id
     * @return
     */
    @Override
    public List<MenuVo> getAllList(String id) {

        LambdaQueryWrapper<Menu> lqw = new LambdaQueryWrapper<>();
        lqw.orderByDesc(Menu::getSort);
        lqw.eq(Menu::getStatus, ServiceConstant.STATUS_ENABLE);
        lqw.eq(Menu::getMenuType, EMenuType.MENU);
        lqw.eq(StringUtils.isNotBlank(id),Menu::getId, id);
        List<Menu> list = list(lqw);

        if (CollectionUtils.isEmpty(list)){
            return new ArrayList<>();
        }
        //获取所有的ID，去寻找他的子目录
        List<String> ids = new ArrayList<>();
        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getId())) {
                ids.add(item.getId());
            }
        });

        // 获取子菜单
        LambdaQueryWrapper<Menu> childLqw = new LambdaQueryWrapper<>();
        childLqw.in(Menu::getParentId, ids);
        childLqw.eq(Menu::getStatus, ServiceConstant.STATUS_ENABLE);
        List<Menu> childList = list(childLqw);

        List<Menu> buttonList;
        if (CollectionUtils.isEmpty(childList)){
            buttonList = new ArrayList<>(1);
        }else {
            //获取所有的二级菜单，去寻找他的子按钮
            List<String> secondMenuUids = new ArrayList<>();
            childList.forEach(item -> {
                if (StringUtils.isNotEmpty(item.getId())) {
                    secondMenuUids.add(item.getId());
                }
            });
            LambdaQueryWrapper<Menu> buttonLqw = new LambdaQueryWrapper<>();
            buttonLqw.in(Menu::getParentId, secondMenuUids);
            buttonLqw.eq(Menu::getStatus, ServiceConstant.STATUS_ENABLE);
            buttonList = list(buttonLqw);
        }


        Map<String, List<MenuVo>> map = new HashMap<>();
        buttonList.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getParentId())) {
                if (map.get(item.getParentId()) == null) {
                    List<MenuVo> tempList = new ArrayList<>();
                    tempList.add(item.toVo());
                    map.put(item.getParentId(), tempList);
                } else {
                    List<MenuVo> tempList = map.get(item.getParentId());
                    tempList.add(item.toVo());
                    map.put(item.getParentId(), tempList);
                }
            }
        });

        // 给二级菜单设置三级按钮
        List<MenuVo> childVoList = childList.stream().map(item -> {
            if (map.get(item.getId()) != null) {
                List<MenuVo> tempList = map.get(item.getId());
                tempList.sort(new Comparator<MenuVo>() {
                    /*
                     * int compare(Menu p1, Menu p2) 返回一个基本类型的整型，
                     * 返回负数表示：p1 小于p2，
                     * 返回0 表示：p1和p2相等，
                     * 返回正数表示：p1大于p2
                     */
                    @Override
                    public int compare(MenuVo o1, MenuVo o2) {
                        //按照Menu的Sort进行降序排列
                        if (o1.getSort() > o2.getSort()) {
                            return -1;
                        }
                        if (o1.getSort().equals(o2.getSort())) {
                            return 0;
                        }
                        return 1;
                    }
                });
                MenuVo menuVo = item.toVo();
                menuVo.setChildMenu(tempList);
                return menuVo;
            } else {
                return item.toVo();
            }
        }).toList();


        // 给一级菜单设置二级菜单
        return list.stream().map(parentItem -> {
            List<MenuVo> tempList = new ArrayList<>();
            for (MenuVo item : childVoList) {
                if (item.getParentId().equals(parentItem.getId())) {
                    tempList.add(item);
                }
            }
            tempList.sort(new Comparator<MenuVo>() {
                @Override
                public int compare(MenuVo o1, MenuVo o2) {
                    if (o1.getSort() > o2.getSort()) {
                        return -1;
                    }
                    if (o1.getSort().equals(o2.getSort())) {
                        return 0;
                    }
                    return 1;
                }
            });
            MenuVo menuVo = parentItem.toVo();
            menuVo.setChildMenu(tempList);
            return menuVo;
        }).toList();
    }




    /**
     * 新增菜单
     *
     * @param form
     */
    @Override
    public boolean addMenu(MenuForm form) {

        Menu menu = new Menu();
        BeanUtils.copyProperties(form,menu);
        return save(menu);
    }


    /**
     * 更新菜单
     *
     * @param form
     */
    @Override
    public boolean updateMenu(MenuForm form) {

        Menu menu = getById(form.getId());
        menu.setParentId(form.getParentId());
        menu.setSort(form.getSort());
        menu.setIcon(form.getIcon());
        menu.setSummary(form.getSummary());
        menu.setMenuType(form.getMenuType());
        menu.setName(form.getName());
        menu.setUrl(form.getUrl());
        menu.setIsShow(form.getIsShow());
        menu.setIsJumpExternalUrl(form.getIsJumpExternalUrl());
        return updateById(menu);
    }


    /**
     * 批量删除菜单
     *
     * @param ids
     */
    @Override
    @Transactional
    public boolean deleteByIds(Collection<String> ids) {

        if (CollectionUtils.isEmpty(ids)){
            return false;
        }
        LambdaQueryWrapper<Menu> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Menu::getStatus, ServiceConstant.STATUS_ENABLE);
        lqw.in(Menu::getParentId, ids);
        long count = count(lqw);
        if (count > 0) {
            throw new BusinessException("菜单下还有子菜单！");
        }
        return removeBatchByIds(ids);
    }



}
